package com.sc.nft.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.convert.Convert;
import cn.hutool.core.date.DateField;
import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.lang.Assert;
import cn.hutool.core.util.IdUtil;
import cn.hutool.core.util.NumberUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.sc.nft.dao.*;
import com.sc.nft.dto.EcologyHatchConfDao;
import com.sc.nft.dto.UserEcologyHatchRecordsDao;
import com.sc.nft.entity.*;
import com.sc.nft.entity.dto.GasConsumeDTO;
import com.sc.nft.entity.vo.ecology.*;
import com.sc.nft.enums.*;
import com.sc.nft.exception.GlobalException;
import com.sc.nft.exception.GlobalRunTimeException;
import com.sc.nft.service.*;
import com.sc.nft.util.BigDecimalUtils;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.compress.utils.Lists;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.stream.Collectors;
import java.util.stream.Stream;

@Slf4j
@RequiredArgsConstructor
@Service
public class EcologyReforgeConfServiceImpl implements EcologyReforgeConfService {

    private final EcologyReforgeConfDao ecologyReforgeConfDao;
    private final DigitalCollectionDao digitalCollectionDao;
    private final DigitalCollectionProductInfoDao digitalCollectionProductInfoDao;
    private final EcologyHatchConfDao ecologyHatchConfDao;
    private final UserEcologyHatchCollectionRecordsDao userEcologyHatchCollectionRecordsDao;
    private final ProductStockDao productStockDao;
    private final EcologyReforgeExpendConfDao ecologyReforgeExpendConfDao;
    private final StaticDataDao staticDataDao;
    private final UserEcologyHatchRecordsDao userEcologyHatchRecordsDao;
    private final UserEcologyReforgeUpperLimitDao userEcologyReforgeUpperLimitDao;
    private final UserEcologyPointsService userEcologyPointsService;
    private final UserEquityPropsService userEquityPropsService;
    private final FilterIncomeListDao filterIncomeListDao;
    private final UserEcologyReforgeUpperLimitService userEcologyReforgeUpperLimitService;
    private final ProductStockService productStockService;
    private final BoxItemService boxItemService;
    private final BoxProductDao boxProductDao;
    private final UserCollectionService userCollectionService;
    private final UserEcologyReforgeRecordsDao userEcologyReforgeRecordsDao;
    private final UserEcologyReforgeRecordsDetailsDao userEcologyReforgeRecordsDetailsDao;
    private final ExitConsensusUserDao exitConsensusUserDao;
    private final UserEcologyReforgeUpperLimitDetailsDao userEcologyReforgeUpperLimitDetailsDao;
    private final UserConsensusService userConsensusService;
    private final UserCityServerCentreDao userCityServerCentreDao;
    private final UserCreatorInfoDao userCreatorInfoDao;
    private final UserWalletDao userWalletDao;
    private final OrderGasService orderGasService;

    private final UserEcologyPointsWalletService userEcologyPointsWalletService;
    private final EcologyPointsService ecologyPointsService;
    @Override
    public List<EcologyReforgeConf> getListByStatus(Boolean status) {
        return ecologyReforgeConfDao.getListByStatus(status);
    }

    /**
     * 回流库存
     * 1. 获取昨日回流数量
     * 2. 计算回流数量
     * 3. 获取商品库存信息
     * 4. 更新商品库存
     *
     * @param ecologyReforgeConf
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void addProductStock(EcologyReforgeConf ecologyReforgeConf) {
        if (ObjectUtil.isNull(ecologyReforgeConf)) {
            return;
        }
        DigitalCollection collection = digitalCollectionDao.getById(ecologyReforgeConf.getCollectionId());
        if (ObjectUtil.isNull(collection)) {
            return;
        }

        if (ObjectUtil.isNull(digitalCollectionProductInfoDao.getById(ecologyReforgeConf.getProductId()))) {
            return;
        }

        EcologyHatchConf ecologyHatchConf = ecologyHatchConfDao.getOneByCollectionId(ecologyReforgeConf.getCollectionId());
        if (ObjectUtil.isNull(ecologyHatchConf)) {
            return;
        }

        DateTime yesterday = DateUtil.offset(DateTime.now(), DateField.DAY_OF_YEAR, -1);
        //昨日回流数量
        Integer yesterdayReforgeCount = userEcologyHatchCollectionRecordsDao.getCountByCollectionAndYesterday(ecologyHatchConf.getId(), ecologyReforgeConf.getCollectionId(), UserEcologyHatchCollectionTypeRecordsEnum.RECYCLE, DateUtil.beginOfDay(yesterday), DateUtil.endOfDay(yesterday));
        if (ObjectUtil.isNull(yesterdayReforgeCount) || yesterdayReforgeCount.intValue() == 0) {
            return;
        }
        //回流数量
        BigDecimal count = Convert.toBigDecimal(yesterdayReforgeCount).multiply(ecologyReforgeConf.getRefluxRatio()).movePointLeft(2).setScale(0, RoundingMode.CEILING);
        if (ObjectUtil.isNull(count) || NumberUtil.isLess(count, BigDecimal.ZERO) || count.intValue() > collection.getUsableCount()) {
            return;
        }

        //获取商品库存信息
        ProductStock productStock = productStockDao.getOneByProductIdAndRelationIdAndType(ecologyReforgeConf.getProductId(), ecologyReforgeConf.getCollectionId(), StockType.COLLECTION);
        if (ObjectUtil.isNull(productStock)) {
            return;
        }

        //减去藏品的可用库存
        Assert.isTrue(digitalCollectionDao.subUsableStock(ecologyReforgeConf.getCollectionId(), count.intValue()) > 0, () -> new GlobalRunTimeException(StrUtil.format("商品库存回流失败,productId:{},collectionId:{},count:{}", ecologyReforgeConf.getProductId(), ecologyReforgeConf.getCollectionId(), count)));
        //商品新增库存
        Assert.isTrue(productStockDao.addUsableCountById(productStock.getId(), count.intValue(), productStock.getVersion()), () -> new GlobalRunTimeException(StrUtil.format("商品库存回流失败,productId:{},collectionId:{},count:{}", ecologyReforgeConf.getProductId(), ecologyReforgeConf.getCollectionId(), count)));


        EcologyRefluxRecords ecologyRefluxRecords = new EcologyRefluxRecords();
        ecologyRefluxRecords.setCollectionId(ecologyReforgeConf.getCollectionId());
        ecologyRefluxRecords.setProductId(ecologyReforgeConf.getProductId());
        ecologyRefluxRecords.setAddCount(count.longValue());
        ecologyRefluxRecords.setBeforeUsableCount(productStock.getUsableCount());
        ecologyRefluxRecords.setAfterUsableCount(productStock.getUsableCount() + count.intValue());
        ecologyRefluxRecords.setRefluxCount(count.longValue());
        ecologyRefluxRecords.setScale(ecologyReforgeConf.getRefluxRatio());
        ecologyRefluxRecords.insert();


    }

    /**
     * 获取生态重铸配置
     *
     * @param id
     * @return
     */
    @Override
    public EcologyReforgeConf getById(Long id) {
        return ecologyReforgeConfDao.getById(id);
    }

    /**
     * 获取生态重铸列表
     *
     * @return
     */
    @Override
    public Page<EcologyReforgeListVO> list(Integer pageNo, Integer pageSize,Long userCreatorId, UserInfo userInfo) {
//        List<Long> collectionIds = getCanCollectionIdsByUserId(userInfo.getId());
        return ecologyReforgeConfDao.getPageEcologyReforge(pageNo, pageSize, new ArrayList<>(),userCreatorId);
    }

    private List<Long> getCanCollectionIdsByUserId(Long userId) {
        List<Long> collectionIds = new ArrayList<>();
        collectionIds.add(0L);
        List<UserCreatorInfo> daoListByUserId = userCreatorInfoDao.getListByUserId(userId);
        // 特殊处理的daoList
        List<Long> needDisposeDaoIds = new ArrayList<>();
        StaticData needDisposeDaoIdData = staticDataDao.getByType("need_dispose_dao_id");
        if (Objects.nonNull(needDisposeDaoIdData)) {
            String value = needDisposeDaoIdData.getValue();
            List<String> needDisposeDaoIdStrList = StrUtil.split(value, ",");
            if (!CollectionUtils.isEmpty(needDisposeDaoIdStrList)) {
                needDisposeDaoIds.addAll(needDisposeDaoIdStrList.stream().map(Long::valueOf).collect(Collectors.toList()));
            }
        }
        // 是否需要特殊处理
        Boolean needDispose = Boolean.FALSE;

        List<Long> daoIds = userCityServerCentreDao.getDaoUserIdListByUserId(userId);

        if (!CollectionUtils.isEmpty(daoListByUserId)) {
            List<Long> userDaoIds = daoListByUserId.stream().map(userCreatorInfo -> userCreatorInfo.getId()).collect(Collectors.toList());
            for (Long userDaoId : userDaoIds) {
                if (needDisposeDaoIds.contains(userDaoId)) {
                    needDispose = Boolean.TRUE;
                }
            }
            if (!needDispose) {
                userDaoIds.remove(6L);
                userDaoIds.remove(7L);
                if (!CollectionUtils.isEmpty(userDaoIds)){
                    List<DigitalCollection> digitalCollectionList = digitalCollectionDao.getListByDaoIds(userDaoIds);
                    if (!CollectionUtils.isEmpty(digitalCollectionList)) {
                        List<Long> collectId = digitalCollectionList.stream().map(digitalCollection -> digitalCollection.getId()).collect(Collectors.toList());
                        Boolean isExistByCollectionIds = ecologyHatchConfDao.getIsExistByCollectionIds(collectId);
                        if (!isExistByCollectionIds) {
                            StaticData data = staticDataDao.getByType("reforge_collection");
                            if (Objects.nonNull(data)) {
                                String value = data.getValue();
                                List<String> reforgeCollectionIdStrList = StrUtil.split(value, ",");
                                if (reforgeCollectionIdStrList.contains("1057")){
                                    collectId.add(1057L);
                                }
                            }
                            return collectId;
                        }
                    }
                }
            } else {
                daoIds.addAll(userDaoIds);
            }
        }

        if (!CollectionUtils.isEmpty(daoIds)) {
            if (!needDispose) {
                daoIds.remove(6L);
                daoIds.remove(7L);
            }
            if (!CollectionUtils.isEmpty(daoIds)) {
                List<DigitalCollection> digitalCollectionList = digitalCollectionDao.getListByDaoIds(daoIds);
                collectionIds.addAll(digitalCollectionList.stream().map(ecologyHatchConf -> ecologyHatchConf.getId()).collect(Collectors.toList()));
            }
        }
        StaticData data = staticDataDao.getByType("reforge_collection");
        if (Objects.nonNull(data)) {
            String value = data.getValue();
            List<String> reforgeCollectionIdStrList = StrUtil.split(value, ",");
            if (!CollectionUtils.isEmpty(reforgeCollectionIdStrList)) {
                collectionIds.addAll(reforgeCollectionIdStrList.stream().map(Long::valueOf).collect(Collectors.toList()));
            }
        }
        return collectionIds;
    }

    /**
     * 获取生态重铸详情
     *
     * @param id
     * @return
     */
    @Override
    public EcologyReforgeDetailsVO details(Long id, UserInfo user) {
        Date now = new Date();

        EcologyReforgeConf ecologyReforgeConf = ecologyReforgeConfDao.getById(id);
        Assert.notNull(ecologyReforgeConf, () -> new GlobalRunTimeException("生态重铸配置不存在"));
        Assert.isTrue(ecologyReforgeConf.getStatus(), () -> new GlobalRunTimeException("生态重铸配置已下架"));

        EcologyReforgeDetailsVO ecologyReforgeDetails = ecologyReforgeConfDao.getProductDetailsById(id);
        Assert.notNull(ecologyReforgeDetails, () -> new GlobalRunTimeException("生态重铸商品不存在"));

        //初始值
        ecologyReforgeDetails.setType(Boolean.FALSE);

        //生态燃料图片
        String ecologyPointsImage = staticDataDao.getByType("ecology_points_image").getValue();

        ArrayList<EcologyReforgeExpendVO> expendList = Lists.newArrayList();
        //销毁明细
        List<EcologyReforgeExpendConf> list = ecologyReforgeExpendConfDao.getListByEcologyReforgeConfId(id);

        //是否熔炼了该藏品
        ecologyReforgeDetails.setIsHatch(Boolean.TRUE);
        if (ecologyReforgeConf.getIsReforgeCondition()) {
            ecologyReforgeDetails.setIsHatch(userEcologyHatchRecordsDao.getCountByStatusAndUserIdAndCollectionId(user.getId(), UserEcologyHatchRecordsStatus.UNDER_WAY, ecologyReforgeConf.getConditionCollectionId()) > 0);
        }
        ecologyReforgeDetails.setHatchName(ecologyReforgeConf.getConditionCollectionName());


        //设置重铸上限
        UserEcologyReforgeUpperLimit userEcologyReforgeUpperLimitDetails = userEcologyReforgeUpperLimitDao.getOneByUserIdAndCollectionId(user.getId(), ecologyReforgeConf.getCollectionId());

        ecologyReforgeDetails.setUpperLimit(ecologyReforgeDetails.getUsableCount());
        ecologyReforgeDetails.setUserUsableCount(ObjectUtil.isNull(userEcologyReforgeUpperLimitDetails) ? 0 : userEcologyReforgeUpperLimitDetails.getUsableCount());
        HashSet<Boolean> booleans = new HashSet<>();
        for (EcologyReforgeExpendConf ecologyReforgeExpendConf : list) {

            EcologyReforgeExpendVO ecologyReforgeExpendVO = BeanUtil.copyProperties(ecologyReforgeExpendConf, EcologyReforgeExpendVO.class);

            if (ecologyReforgeExpendConf.getExpendType() == EcologyExpendType.ECOLOGY_POINTS) {
                UserEcologyPoints userEcologyPoints = userEcologyPointsService.getOneByUserId(user.getId());
                ecologyReforgeExpendVO.setHoldCount(userEcologyPoints.getAmount());
                ecologyReforgeExpendVO.setExpendImage(ecologyPointsImage);
                ecologyReforgeExpendVO.setExpendCount(ecologyReforgeExpendConf.getExpendCount());
                if (userEcologyPoints.getAmount().compareTo(ecologyReforgeExpendConf.getExpendCount()) > -1) {//用户持有数量大于等于消耗数量
                    booleans.add(Boolean.TRUE);
                } else {
                    booleans.add(Boolean.FALSE);
                }
            }

            if (ecologyReforgeExpendConf.getExpendType() == EcologyExpendType.EQUITY_PROPS) {
                Integer havingCount = userEquityPropsService.getHavingCountByUserId(ecologyReforgeExpendConf.getExpendId(), user.getId());
                ecologyReforgeExpendVO.setHoldCount(Convert.toBigDecimal(havingCount));
                ecologyReforgeExpendVO.setExpendCount(ecologyReforgeExpendConf.getExpendCount());

                if (Convert.toBigDecimal(havingCount).compareTo(ecologyReforgeExpendConf.getExpendCount()) > -1) {//用户持有数量大于等于消耗数量
                    booleans.add(Boolean.TRUE);
                } else {
                    booleans.add(Boolean.FALSE);
                }
            }
            if (ecologyReforgeExpendConf.getExpendType() == EcologyExpendType.ECOLOGY_MARK) {
                UserEcologyPointsWallet userEcologyPointsWallet = userEcologyPointsWalletService.getOneByUserIdAndPointId(ecologyReforgeExpendConf.getExpendId(),user.getId());
                BigDecimal amount = BigDecimal.ZERO;
                if (Objects.nonNull(userEcologyPointsWallet)) {
                    amount = userEcologyPointsWallet.getAmount();
                }
                ecologyReforgeExpendVO.setHoldCount(amount);
                ecologyReforgeExpendVO.setExpendImage(ecologyPointsImage);
                ecologyReforgeExpendVO.setExpendCount(ecologyReforgeExpendConf.getExpendCount());
                if (amount.compareTo(ecologyReforgeExpendConf.getExpendCount()) > -1) {//用户持有数量大于等于消耗数量
                    booleans.add(Boolean.TRUE);
                } else {
                    booleans.add(Boolean.FALSE);
                }
            }

            expendList.add(ecologyReforgeExpendVO);
        }
        ProductStock productStock = productStockDao.getByProductId(ecologyReforgeDetails.getProductId());
        ecologyReforgeDetails.setUsableCount(ObjectUtil.isNull(productStock) ? 0 : productStock.getUsableCount());

//        DigitalCollectionProductInfo productInfo = digitalCollectionProductInfoDao.getById(ecologyReforgeDetails.getProductId());

        Date reforgeStartTime = now;
        Date reforgeEndTime = now;
        try {
            // 重铸开始时间
            String pattern = "yyyyMMddHHmmss";
            // 创建SimpleDateFormat对象，指定日期格式
            SimpleDateFormat dateFormat = new SimpleDateFormat(pattern);
            String nowStr = DateUtil.format(now, "yyyyMMdd");
            String reforgeStartTimeStr = staticDataDao.getByType("reforge_start_time").getValue();
            String reforgeEndTimeStr = staticDataDao.getByType("reforge_end_time").getValue();
            reforgeStartTime = dateFormat.parse(nowStr + reforgeStartTimeStr);
            reforgeEndTime = dateFormat.parse(nowStr + reforgeEndTimeStr);
        } catch (Exception e) {
            log.error("重铸时间配置有误");
        }
        ecologyReforgeDetails.setReforgeButtonType(ReforgeButtonTypeEnum.REFORGE);
        if (now.after(reforgeStartTime) && now.before(reforgeEndTime)) {
            if (ecologyReforgeDetails.getUsableCount() <= 0) {
                ecologyReforgeDetails.setReforgeButtonType(ReforgeButtonTypeEnum.INSUFFICIENT_STOCK);
                booleans.add(Boolean.FALSE);
            } else {
                booleans.add(Boolean.TRUE);
            }
        } else {
            ecologyReforgeDetails.setReforgeButtonType(ReforgeButtonTypeEnum.HAVE_NOT_STARTED_YET);
            booleans.add(Boolean.FALSE);
        }

        // 获取已经使用的次数
//        Integer useFreeCount = userEcologyReforgeRecordsDetailsDao.getUseFreeCount(user.getId(), ecologyReforgeConf.getCollectionId());
//        Integer needAddCount = 0;
//        if (ecologyReforgeConf.getReforgeFreeCount().intValue() > useFreeCount.intValue()) {
//            needAddCount = ecologyReforgeConf.getReforgeFreeCount() - useFreeCount;
//        }
        if (booleans.contains(Boolean.FALSE)) {
            ecologyReforgeDetails.setType(Boolean.FALSE);
        } else {
            ecologyReforgeDetails.setType(Boolean.TRUE);
        }
//        }

        ecologyReforgeDetails.setExpendList(expendList);
        DigitalCollectionProductInfo productInfo = digitalCollectionProductInfoDao.getById(ecologyReforgeDetails.getProductId());
        ecologyReforgeDetails.setProductDetailPictureType(productInfo.getProductDetailPictureType());
        ecologyReforgeDetails.setModelImg(productInfo.getModelImg());
        ecologyReforgeDetails.setModelDistance(productInfo.getModelDistance());
        ecologyReforgeDetails.setProductPresentation(productInfo.getEcologyCastPresentation());
        ecologyReforgeDetails.setProductDetailPicture(productInfo.getProductDetailPicture());
        ecologyReforgeDetails.setIsLockedPosition(productInfo.getIsLockedPosition());
        ecologyReforgeDetails.setLockedPositionType(productInfo.getLockedPositionType());
        ecologyReforgeDetails.setLockedPositionHour(productInfo.getLockedPositionHour());
        ecologyReforgeDetails.setLockedPositionTime(productInfo.getLockedPositionTime());
        ecologyReforgeDetails.setLockedPositionDescribe();
        EcologyHatchConf ecologyHatchConf = ecologyHatchConfDao.getOneByCollectionId(ecologyReforgeConf.getCollectionId());
        ecologyReforgeDetails.setAddReforgeCount(ObjectUtil.isNull(ecologyHatchConf) ? 0 : ecologyHatchConf.getAddReforgeCount());
        ecologyReforgeDetails.setUpperLimit(ecologyReforgeDetails.getUsableCount());
        ecologyReforgeDetails.setUserUsableCount(ecologyReforgeDetails.getUsableCount());
        ecologyReforgeDetails.setUsableCount(ecologyReforgeDetails.getUsableCount());
        ecologyReforgeDetails.setReforgeFreeCount(0);
        if (filterIncomeListDao.checkIsFilterAccount(digitalCollectionDao.getById(ecologyReforgeConf.getCollectionId()).getUserCreatorId(), user.getId())
                || filterIncomeListDao.checkListIsFilterAccount(Arrays.asList(6L, 7L, 131L, 145L), user.getId())) {
            ecologyReforgeDetails.setType(Boolean.TRUE);
            ecologyReforgeDetails.setUpperLimit(ecologyReforgeDetails.getUsableCount());
            ecologyReforgeDetails.setUserUsableCount(ecologyReforgeDetails.getUsableCount());
            ecologyReforgeDetails.setUsableCount(ecologyReforgeDetails.getUsableCount());
            ecologyReforgeDetails.setIsHatch(Boolean.TRUE);
        }
        //获取上链费信息
        if (productInfo.getGasConf()) {
            EcologyCastGasVO ecologyCastGas = new EcologyCastGasVO();
            ecologyCastGas.setConsumeType(productInfo.getConsumeType());
            ecologyCastGas.setGasConf(productInfo.getGasConf());
            ecologyCastGas.setConsumeCost(productInfo.getConsumeCost());
            ecologyReforgeDetails.setEcologyCastGas(ecologyCastGas);
            UserWallet userWallet = userWalletDao.getByUserId(user.getId());
            ecologyCastGas.setBalance(Objects.isNull(userWallet)?BigDecimal.ZERO:userWallet.getBalance());
        }
        return ecologyReforgeDetails;
    }

    /**
     * 获取重铸所需数量
     *
     * @param id
     * @param count
     * @param user
     * @return
     */
    @Override
    public List<EcologyReforgeExpendVO> preExpendDetails(Long id, Integer count, UserInfo user) {
        EcologyReforgeConf ecologyReforgeConf = ecologyReforgeConfDao.getById(id);
        Assert.notNull(ecologyReforgeConf, () -> new GlobalRunTimeException("生态重铸配置不存在"));
        Assert.isTrue(ecologyReforgeConf.getStatus(), () -> new GlobalRunTimeException("生态重铸配置已下架"));

        EcologyReforgeDetailsVO ecologyReforgeDetails = ecologyReforgeConfDao.getProductDetailsById(id);
        Assert.notNull(ecologyReforgeDetails, () -> new GlobalRunTimeException("生态重铸商品不存在"));

        ArrayList<EcologyReforgeExpendVO> expendList = Lists.newArrayList();
        //生态燃料图片
        String ecologyPointsImage = staticDataDao.getByType("ecology_points_image").getValue();

        //销毁明细
        List<EcologyReforgeExpendConf> list = ecologyReforgeExpendConfDao.getListByEcologyReforgeConfId(id);

        for (EcologyReforgeExpendConf ecologyReforgeExpendConf : list) {

            EcologyReforgeExpendVO ecologyReforgeExpendVO = BeanUtil.copyProperties(ecologyReforgeExpendConf, EcologyReforgeExpendVO.class);

            if (ecologyReforgeExpendConf.getExpendType() == EcologyExpendType.ECOLOGY_POINTS) {
                UserEcologyPoints userEcologyPoints = userEcologyPointsService.getOneByUserId(user.getId());
                ecologyReforgeExpendVO.setHoldCount(userEcologyPoints.getAmount());
                ecologyReforgeExpendVO.setExpendImage(ecologyPointsImage);
                ecologyReforgeExpendVO.setExpendCount(ecologyReforgeExpendConf.getExpendCount().multiply(Convert.toBigDecimal(count)));
            }

            if (ecologyReforgeExpendConf.getExpendType() == EcologyExpendType.EQUITY_PROPS) {
                Integer havingCount = userEquityPropsService.getHavingCountByUserId(ecologyReforgeExpendConf.getExpendId(), user.getId());
                ecologyReforgeExpendVO.setHoldCount(Convert.toBigDecimal(havingCount));
                ecologyReforgeExpendVO.setExpendCount(ecologyReforgeExpendConf.getExpendCount().multiply(Convert.toBigDecimal(count)));
            }

            if (ecologyReforgeExpendConf.getExpendType() == EcologyExpendType.ECOLOGY_MARK) {
                UserEcologyPointsWallet userEcologyPointsWallet = userEcologyPointsWalletService.getOneByUserIdAndPointId(ecologyReforgeExpendConf.getExpendId(),user.getId());
                BigDecimal amount = BigDecimal.ZERO;
                if (Objects.nonNull(userEcologyPointsWallet)) {
                    amount = userEcologyPointsWallet.getAmount();
                }
                ecologyReforgeExpendVO.setHoldCount(amount);
                ecologyReforgeExpendVO.setExpendImage(ecologyPointsImage);
                ecologyReforgeExpendVO.setExpendCount(ecologyReforgeExpendConf.getExpendCount());
            }

            expendList.add(ecologyReforgeExpendVO);
        }

        return expendList;
    }

    /**
     * 重铸
     *
     * @param id
     * @param count
     * @param user
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void expend(Long id, Integer count, UserInfo user) throws GlobalException {
        Date now = new Date();
        Date reforgeStartTime = now;
        Date reforgeEndTime = now;
        try {
            // 重铸开始时间
            String pattern = "yyyyMMddHHmmss";
            // 创建SimpleDateFormat对象，指定日期格式
            SimpleDateFormat dateFormat = new SimpleDateFormat(pattern);
            String nowStr = DateUtil.format(now, "yyyyMMdd");
            String reforgeStartTimeStr = staticDataDao.getByType("reforge_start_time").getValue();
            String reforgeEndTimeStr = staticDataDao.getByType("reforge_end_time").getValue();
            reforgeStartTime = dateFormat.parse(nowStr + reforgeStartTimeStr);
            reforgeEndTime = dateFormat.parse(nowStr + reforgeEndTimeStr);
        } catch (Exception e) {
            log.error("重铸时间配置有误");
        }
        if (now.before(reforgeStartTime) || now.after(reforgeEndTime)) {
            throw new GlobalRunTimeException("重铸暂未开始");
        }

        EcologyReforgeConf ecologyReforgeConf = ecologyReforgeConfDao.getById(id);
        Assert.notNull(ecologyReforgeConf, () -> new GlobalRunTimeException("生态铸造配置不存在"));
        Assert.isTrue(ecologyReforgeConf.getStatus(), () -> new GlobalRunTimeException("生态铸造配置已下架"));

//        List<Long> canCollectionIdsByUserId = getCanCollectionIdsByUserId(user.getId());
//        if (!canCollectionIdsByUserId.contains(ecologyReforgeConf.getCollectionId())) {
//            throw new GlobalRunTimeException("该藏品无法重铸");
//        }
        if (ecologyReforgeConf.getIsReforgeCondition()) {
            if (userEcologyHatchRecordsDao.getCountByStatusAndUserIdAndCollectionId(user.getId(), UserEcologyHatchRecordsStatus.UNDER_WAY, ecologyReforgeConf.getConditionCollectionId()) <= 0) {
                throw new GlobalRunTimeException("该藏品无法重铸");
            }
        }

        EcologyReforgeDetailsVO ecologyReforgeDetails = ecologyReforgeConfDao.getProductDetailsById(id);
        Assert.notNull(ecologyReforgeDetails, () -> new GlobalRunTimeException("生态铸造商品不存在"));
        List<EcologyReforgeExpendConf> list = ecologyReforgeExpendConfDao.getListByEcologyReforgeConfId(id);

        // 获取已经使用的次数
//        Integer useFreeCount = userEcologyReforgeRecordsDetailsDao.getUseFreeCount(user.getId(), ecologyReforgeConf.getCollectionId());
//        Integer freeCount = 0;
//        Integer notFreeCount = count;
//        if (ecologyReforgeConf.getReforgeFreeCount() > useFreeCount) {
//            if (ecologyReforgeConf.getReforgeFreeCount() - useFreeCount > count) {
//                // 可用免费次数大于当前重铸的次数
//                freeCount = count;
//                notFreeCount = 0;
//            } else {
//                // 可用免费次数小于当前重铸的次数
//                freeCount = ecologyReforgeConf.getReforgeFreeCount() - useFreeCount;
//                notFreeCount = count - freeCount;
//            }
//        }
//        UserEcologyReforgeRecordsDetails notFreeUserEcologyReforgeRecordsDetails = new UserEcologyReforgeRecordsDetails();
//        UserEcologyReforgeRecordsDetails freeUserEcologyReforgeRecordsDetails = new UserEcologyReforgeRecordsDetails();
//        if (notFreeCount > 0) {
        // 非免费
        UserEcologyReforgeRecordsDetails userEcologyReforgeRecordsDetails = new UserEcologyReforgeRecordsDetails();
        userEcologyReforgeRecordsDetails.setUserId(user.getId());
        userEcologyReforgeRecordsDetails.setCollectionId(ecologyReforgeConf.getCollectionId());
        userEcologyReforgeRecordsDetails.setEcologyReforgeConfId(ecologyReforgeConf.getId());
        userEcologyReforgeRecordsDetails.setCollectionName(ecologyReforgeConf.getCollectionName());
        userEcologyReforgeRecordsDetails.setReforgeCount(count);
        userEcologyReforgeRecordsDetails.setIsFree(Boolean.FALSE);
        userEcologyReforgeRecordsDetails.insert();

        //如果铸造的藏品 用户不是这个dao的市值账号
        // 1.则需要判断是否达到熔炼上限
        // 2.只有熔炼了才能铸造

        //判断用户是否是dao下的市值账号
//        if (!filterIncomeListDao.checkIsFilterAccount(digitalCollectionDao.getById(ecologyReforgeConf.getCollectionId()).getUserCreatorId(), user.getId())
//                //判断用户是否是市值账号
//                && !filterIncomeListDao.checkListIsFilterAccount(Arrays.asList(6L, 7L, 131L, 145L), user.getId())
//        ) {
//            Assert.isTrue(userEcologyHatchRecordsDao.getCountByStatusAndUserIdAndCollectionId(user.getId(), UserEcologyHatchRecordsStatus.UNDER_WAY, ecologyReforgeConf.getCollectionId()) > 0
//                    , () -> new GlobalRunTimeException("只有参与此藏品熔炼才能铸造"));
            //铸造上限
//            UserEcologyReforgeUpperLimit userEcologyReforgeUpperLimit = userEcologyReforgeUpperLimitDao.getOneByUserIdAndCollectionId(user.getId(), ecologyReforgeConf.getCollectionId());
//            int usableCount = ObjectUtil.isNull(userEcologyReforgeUpperLimit) ? 0 : userEcologyReforgeUpperLimit.getUsableCount();
//
//            //减去铸造上限
//            if (notFreeCount > 0) {
//                Assert.isTrue(usableCount >= notFreeCount.intValue(), () -> new GlobalRunTimeException("铸造数量超过上限"));
//                userEcologyReforgeUpperLimitService.subCountByUserIdAndCollectionId(
//                        user.getId(), ecologyReforgeConf.getCollectionId(), notFreeCount, UserEcologyReforgeUpperLimitDetailsTypeEnum.REFORGE,
//                        StrUtil.format("铸造:{}", ecologyReforgeConf.getCollectionName()), notFreeUserEcologyReforgeRecordsDetails.getId());
//            }

//        }

        for (EcologyReforgeExpendConf ecologyReforgeExpendConf : list) {
            //生态积分
            if (ecologyReforgeExpendConf.getExpendType() == EcologyExpendType.ECOLOGY_POINTS) {
                UserEcologyPoints userEcologyPoints = userEcologyPointsService.getOneByUserId(user.getId());

                BigDecimal sumCount = ecologyReforgeExpendConf.getExpendCount().multiply(Convert.toBigDecimal(count));
                //用户余额 大于 所需数量
                Assert.isTrue(NumberUtil.isGreaterOrEqual(userEcologyPoints.getAmount(), sumCount), () -> new GlobalRunTimeException("生态燃料不足"));
                //扣除燃料
                Assert.isTrue(userEcologyPointsService.subAmount(user.getId(), sumCount, EcologyPointsEnum.REFORGE, StrUtil.EMPTY), () -> new GlobalRunTimeException("铸造失败,请稍后重试!"));
                //添加记录
//                if (notFreeCount > 0) {
                UserEcologyReforgeRecords userEcologyReforgeRecords = new UserEcologyReforgeRecords();
                userEcologyReforgeRecords.setRecordsId(userEcologyReforgeRecordsDetails.getId());
                userEcologyReforgeRecords.setUserId(user.getId());
                userEcologyReforgeRecords.setEcologyReforgeConfId(ecologyReforgeConf.getId());
                userEcologyReforgeRecords.setEcologyReforgeExpendConfId(ecologyReforgeExpendConf.getId());
                userEcologyReforgeRecords.setExpendType(ecologyReforgeExpendConf.getExpendType());
                userEcologyReforgeRecords.setExpendCount(ecologyReforgeExpendConf.getExpendCount().multiply(Convert.toBigDecimal(count)));
                userEcologyReforgeRecords.setExpendName(ecologyReforgeExpendConf.getExpendType().getDescription());
                userEcologyReforgeRecords.setExpendImage(staticDataDao.getByType("ecology_points_image").getValue());
                userEcologyReforgeRecords.setCollectionName(ecologyReforgeConf.getCollectionName());
                userEcologyReforgeRecords.setReforgeCount(count);
                userEcologyReforgeRecords.insert();
//                }
//                if (freeCount > 0) {
//                    UserEcologyReforgeRecords userEcologyReforgeRecords = new UserEcologyReforgeRecords();
//                    userEcologyReforgeRecords.setRecordsId(freeUserEcologyReforgeRecordsDetails.getId());
//                    userEcologyReforgeRecords.setUserId(user.getId());
//                    userEcologyReforgeRecords.setEcologyReforgeConfId(ecologyReforgeConf.getId());
//                    userEcologyReforgeRecords.setEcologyReforgeExpendConfId(ecologyReforgeExpendConf.getId());
//                    userEcologyReforgeRecords.setExpendType(ecologyReforgeExpendConf.getExpendType());
//                    userEcologyReforgeRecords.setExpendCount(ecologyReforgeExpendConf.getExpendCount().multiply(Convert.toBigDecimal(freeCount)));
//                    userEcologyReforgeRecords.setExpendName(ecologyReforgeExpendConf.getExpendType().getDescription());
//                    userEcologyReforgeRecords.setExpendImage(staticDataDao.getByType("ecology_points_image").getValue());
//                    userEcologyReforgeRecords.setCollectionName(ecologyReforgeConf.getCollectionName());
//                    userEcologyReforgeRecords.setReforgeCount(freeCount);
//                    userEcologyReforgeRecords.insert();
//                }
            }
            //权益道具
            if (ecologyReforgeExpendConf.getExpendType() == EcologyExpendType.EQUITY_PROPS) {
                Integer havingCount = userEquityPropsService.getHavingCountByUserId(ecologyReforgeExpendConf.getExpendId(), user.getId());
                Integer sumCount = Convert.toInt(ecologyReforgeExpendConf.getExpendCount().multiply(Convert.toBigDecimal(count)));
                Assert.isTrue(havingCount.intValue() >= sumCount.intValue(), () -> new GlobalRunTimeException("权益道具持有量不足"));

                List<UserEquityProps> userEquityPropsList = userEquityPropsService.getHavingListByUserIdAndEquityPropsIdAndLimit(user.getId(), ecologyReforgeExpendConf.getExpendId(), sumCount);
                Assert.isTrue(userEquityPropsList.size() == sumCount, () -> new GlobalRunTimeException("铸造失败,请稍后重试!"));

                Assert.isTrue(
                        userEquityPropsService.normalToconsumeByIds(userEquityPropsList, user.getId(), ecologyReforgeConf.getProductName(), ecologyReforgeConf.getId(), UserEquityPropsUseTypeEnum.ECOLOGY_REFORGE)
                        , () -> new GlobalRunTimeException("铸造失败,请稍后重试!"));

                //添加记录
//                if (notFreeCount > 0) {
                UserEcologyReforgeRecords userEcologyReforgeRecords = new UserEcologyReforgeRecords();
                userEcologyReforgeRecords.setRecordsId(userEcologyReforgeRecordsDetails.getId());
                userEcologyReforgeRecords.setUserId(user.getId());
                userEcologyReforgeRecords.setEcologyReforgeConfId(ecologyReforgeConf.getId());
                userEcologyReforgeRecords.setEcologyReforgeExpendConfId(ecologyReforgeExpendConf.getId());
                userEcologyReforgeRecords.setExpendType(ecologyReforgeExpendConf.getExpendType());
                userEcologyReforgeRecords.setExpendCount(ecologyReforgeExpendConf.getExpendCount().multiply(Convert.toBigDecimal(count)));
                userEcologyReforgeRecords.setExpendName(ecologyReforgeExpendConf.getExpendName());
                userEcologyReforgeRecords.setExpendImage(ecologyReforgeExpendConf.getExpendImage());
                userEcologyReforgeRecords.setExpendId(ecologyReforgeExpendConf.getExpendId());
                userEcologyReforgeRecords.setCollectionName(ecologyReforgeConf.getCollectionName());
                userEcologyReforgeRecords.setReforgeCount(count);
                userEcologyReforgeRecords.insert();
//                }
//                if (freeCount > 0) {
//                    UserEcologyReforgeRecords userEcologyReforgeRecords = new UserEcologyReforgeRecords();
//                    userEcologyReforgeRecords.setRecordsId(freeUserEcologyReforgeRecordsDetails.getId());
//                    userEcologyReforgeRecords.setUserId(user.getId());
//                    userEcologyReforgeRecords.setEcologyReforgeConfId(ecologyReforgeConf.getId());
//                    userEcologyReforgeRecords.setEcologyReforgeExpendConfId(ecologyReforgeExpendConf.getId());
//                    userEcologyReforgeRecords.setExpendType(ecologyReforgeExpendConf.getExpendType());
//                    userEcologyReforgeRecords.setExpendCount(ecologyReforgeExpendConf.getExpendCount().multiply(Convert.toBigDecimal(freeCount)));
//                    userEcologyReforgeRecords.setExpendName(ecologyReforgeExpendConf.getExpendName());
//                    userEcologyReforgeRecords.setExpendImage(ecologyReforgeExpendConf.getExpendImage());
//                    userEcologyReforgeRecords.setExpendId(ecologyReforgeExpendConf.getExpendId());
//                    userEcologyReforgeRecords.setCollectionName(ecologyReforgeConf.getCollectionName());
//                    userEcologyReforgeRecords.setReforgeCount(freeCount);
//                    userEcologyReforgeRecords.insert();
//                }
            }

            //积分
            if (ecologyReforgeExpendConf.getExpendType() == EcologyExpendType.ECOLOGY_MARK) {
                EcologyPoints ecologyPoints = ecologyPointsService.getById(ecologyReforgeExpendConf.getExpendId());
                Assert.notNull(ecologyPoints,()-> new GlobalRunTimeException("积分不存在"));
                UserEcologyPointsWallet userEcologyPointsWallet = userEcologyPointsWalletService.getOneByUserIdAndPointId(ecologyReforgeExpendConf.getExpendId(),user.getId());
                BigDecimal amount = BigDecimal.ZERO;
                if (Objects.nonNull(userEcologyPointsWallet)) {
                    amount = userEcologyPointsWallet.getAmount();
                }

                BigDecimal sumCount = ecologyReforgeExpendConf.getExpendCount().multiply(Convert.toBigDecimal(count));
                //用户余额 大于 所需数量
                Assert.isTrue(NumberUtil.isGreaterOrEqual(amount, sumCount), () -> new GlobalRunTimeException("积分不足"));
                //扣除积分
                Assert.isTrue(userEcologyPointsWalletService.adjustAmount(user.getId(),ecologyReforgeExpendConf.getExpendId(),ecologyReforgeExpendConf.getExpendName(), sumCount, EcologyPointsWalletEnum.REFORGE, StrUtil.EMPTY), () -> new GlobalRunTimeException("铸造失败,请稍后重试!"));
                //添加记录
                //添加记录
                UserEcologyReforgeRecords userEcologyReforgeRecords = new UserEcologyReforgeRecords();
                userEcologyReforgeRecords.setRecordsId(userEcologyReforgeRecordsDetails.getId());
                userEcologyReforgeRecords.setUserId(user.getId());
                userEcologyReforgeRecords.setEcologyReforgeConfId(ecologyReforgeConf.getId());
                userEcologyReforgeRecords.setEcologyReforgeExpendConfId(ecologyReforgeExpendConf.getId());
                userEcologyReforgeRecords.setExpendType(ecologyReforgeExpendConf.getExpendType());
                userEcologyReforgeRecords.setExpendCount(ecologyReforgeExpendConf.getExpendCount().multiply(Convert.toBigDecimal(count)));
                userEcologyReforgeRecords.setExpendName(ecologyReforgeExpendConf.getExpendName());
                userEcologyReforgeRecords.setExpendImage(ecologyReforgeExpendConf.getExpendImage());
                userEcologyReforgeRecords.setExpendId(ecologyReforgeExpendConf.getExpendId());
                userEcologyReforgeRecords.setCollectionName(ecologyReforgeConf.getCollectionName());
                userEcologyReforgeRecords.setReforgeCount(count);
                userEcologyReforgeRecords.insert();
            }


        }

        DigitalCollectionProductInfo prduct = digitalCollectionProductInfoDao.getById(ecologyReforgeDetails.getProductId());

        //重铸上链费
        if (prduct.getGasConf()) {
            GasConsumeDTO gasConsume = getGasConsumeDTO(user, prduct);
            orderGasService.gasConsume(gasConsume);
        }

        boolean isOpen = false;
        Long boxId = null;
        String boxTitle = null;
        String boxImage = null;
        Long collectionId = null;
        for (int i = 0; i < count; i++) {
            switch (prduct.getTypeClassify()) {
                case COLLECTION:
                    collectionId = prduct.getRelationId();
                    isOpen = true;
                    Assert.isTrue(productStockService.deductStock(prduct.getId(), prduct.getRelationId(), 1, user.getId(), CommodityType.ECOLOGY_COMMODITY), () -> new GlobalRunTimeException("库存不足"));
                    break;
                case BLIND_BOX:
                    BoxItem boxItem = boxItemService.openBox(prduct.getId(), prduct.getRelationId());
                    collectionId = boxItem.getCollectionId();
                    Assert.isTrue(productStockService.subItemStock(prduct.getId(), prduct.getRelationId(), boxItem.getId(), 1, user.getId(), CommodityType.ECOLOGY_COMMODITY), () -> new GlobalRunTimeException("库存不足"));
                    BoxProduct boxProduct = boxProductDao.getById(prduct.getRelationId());
                    boxId = boxProduct.getId();
                    boxTitle = boxProduct.getFirstTitle();
                    boxImage = prduct.getCreationContent();
                    isOpen = false;
                    break;
            }
            DigitalCollection digitalCollection = digitalCollectionDao.getById(collectionId);
            UserCollection userCollection = userCollectionService.addCollection(user.getId(), null, digitalCollection.getId(), IdUtil.getSnowflakeNextIdStr(), digitalCollection.getCreationContent(), digitalCollection.getLevel(), digitalCollection.getFirstTitle(),
                    digitalCollection.getUserCreatorId(), ReceivedCollectionType.ECOLOGY_HATCH, boxId, boxTitle, boxImage, isOpen, prduct.getId(), 0L, 0L, BigDecimal.ZERO, 0, null, null, AddCollectionEnum.STAIR, null, null,false);

            //藏品流转表记录
            CollectionCirculatingRecord collectionCirculatingRecord = new CollectionCirculatingRecord();
            collectionCirculatingRecord.setUserId(user.getId());
            collectionCirculatingRecord.setCollectionId(digitalCollection.getId());
            collectionCirculatingRecord.setCommodityType(CommodityType.ECOLOGY_COMMODITY);
            collectionCirculatingRecord.setTypeClassify(prduct.getTypeClassify());
            collectionCirculatingRecord.setReceivedCollectionType(ReceivedCollectionType.ECOLOGY_HATCH);
            collectionCirculatingRecord.setToUserCollection(userCollection.getId());
            collectionCirculatingRecord.setOrderId(0L);
            collectionCirculatingRecord.insert();
        }
        ExitConsensusUser exitConsensusUser = exitConsensusUserDao.getByUserId(user.getId());
        Boolean isConsensus = ObjectUtil.isNull(exitConsensusUser) || !exitConsensusUser.getStatus();
        if (isConsensus) {
            userConsensusService.adjustConsensusService(user.getId(), ecologyReforgeConf.getCollectionId(), BigDecimal.valueOf(count), UserConsensusTypeEnums.RECAST, ecologyReforgeConf.getCollectionName(), null);
        }

    }

    private static GasConsumeDTO getGasConsumeDTO(UserInfo user, DigitalCollectionProductInfo prduct) {
        GasConsumeDTO gasConsume=new GasConsumeDTO();
        gasConsume.setConsumeCost(prduct.getConsumeCost());
        gasConsume.setUserId(user.getId());
        gasConsume.setGasConsumeType(prduct.getConsumeType());
        gasConsume.setWalletDetailType(WalletDetailTypeEnum.GAS_ECOLOGY_REFORGE_EXPEND);
        gasConsume.setProductId(prduct.getId());
        gasConsume.setCollectionId(prduct.getRelationId());
        gasConsume.setOrderGasType(OrderGasTypeEnum.GAS_ECOLOGY_REFORGE_EXPEND);
        return gasConsume;
    }

    /**
     * 获取重铸消耗记录
     *
     * @param user
     * @param pageNo
     * @param pageSize
     * @return
     */
    @Override
    public Page<ExpendEcologyReforgeRecordsVO> expendRecords(UserInfo user, Integer pageNo, Integer pageSize) {
        return userEcologyReforgeRecordsDao.expendRecords(user.getId(), pageNo, pageSize);
    }

    @Override
    public Page<UserReforgeExpendRecordsPageVO> expendRecordsPage(UserInfo user, Integer pageNo, Integer pageSize,Long userCreatorId) {
        return userEcologyReforgeRecordsDetailsDao.expendRecordsPage(user.getId(), pageNo, pageSize,userCreatorId);
    }

    @Override
    public List<ExpendEcologyReforgeRecordsVO> expendRecordsDetails(UserInfo user, Long id) {
        return userEcologyReforgeRecordsDao.expendRecordsDetails(user.getId(), id);
    }

    /**
     * 用户重铸上限记录
     *
     * @param user
     * @param pageNo
     * @param pageSize
     * @return
     */
    @Override
    public Page<UserEcologyReforgeUpperLimitDetailsVO> userEcologyReforgeUpperLimitDetails(UserInfo user, Long id, Integer pageNo, Integer pageSize) {
        EcologyReforgeConf ecologyReforgeConf = ecologyReforgeConfDao.getById(id);
        Assert.notNull(ecologyReforgeConf, () -> new GlobalRunTimeException("生态重铸配置不存在"));

        return userEcologyReforgeUpperLimitDetailsDao.getUserEcologyReforgeUpperLimitDetails(user.getId(), ecologyReforgeConf.getCollectionId(), pageNo, pageSize);
    }

}
